home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / telecomm / zmdm.zoo / transfer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-27  |  16.4 KB  |  986 lines

  1. /*
  2.  *     (Quick & Dirty) Transfer Shell
  3.  *
  4.  *    Jwahar Bammi
  5.  *     bang:   {any internet host}!dsrgsun.ces.CWRU.edu!bammi
  6.  *     domain: bammi@dsrgsun.ces.CWRU.edu
  7.  *    GEnie:    J.Bammi
  8.  */
  9.  
  10. #include "config.h"
  11.  
  12. #ifdef DLIBS
  13. #include <string.h>
  14. #endif
  15. #ifdef __GNUC__
  16. #include <string.h>
  17. #endif
  18.  
  19. #include "zmdm.h"
  20. #include "common.h"
  21.  
  22. #define ISWILD(X)    ((X == '*')||(X == '?'))
  23. #define PROMPT        fprintf(STDERR,"zmdm> ")
  24.  
  25. extern int dorz(), dosz(), ls(), rm(), cp(), cd(), md(), rd(), pwd(), df(),
  26.        hhelp();
  27.  
  28. #ifdef RECURSE
  29. extern int doszf();
  30. #endif
  31.  
  32. static struct comnds {
  33.     char    *command;    /* command string    */
  34.     int     (*routine)();    /* routine to invoke    */
  35.     char    *synopsis;    /* synopsis        */
  36.     int    expand;        /* expand wildcards before calling routine? */
  37. } comtab [] = {
  38.     { "rz",    dorz, "receive files using Z/X modem protocol",       TRUE },
  39.     { "rb", dorz, "receive files using Y modem protocol",         TRUE },
  40. #ifdef RECURSE
  41.     { "sz", doszf, "send files using Z/Y/X modem protocol",        TRUE },
  42. #else
  43.     { "sz", dosz, "send files using Z/Y/X modem protocol",        TRUE },
  44. #endif
  45.     { "sb", dosz, "send files using Y modem protocol",            TRUE },
  46.     { "rm", rm,   "remove files",                                 TRUE },
  47.     { "cp", cp,   "copy files",                                   TRUE },
  48.     { "ls", ls,   "list directory",                               FALSE},
  49.     { "cd", cd,   "change working directory",              FALSE},
  50.     { "md", md,   "make a directory",                  FALSE},
  51.     { "rd", rd,   "remove a directory",                  FALSE},
  52.     { "pwd",pwd,  "print  working directory",              FALSE},
  53.     { "df", df,   "check free space",                  FALSE},
  54.     { "?",  hhelp, "this message",                      FALSE},
  55.     { (char *)NULL, (int (*)())NULL, (char *)NULL,                FALSE}
  56. };
  57.  
  58. #define MAXARGS    1024
  59. static char *targv[MAXARGS];
  60. static int targc;
  61. char *alltolower();
  62.  
  63. void transfer()
  64. {
  65.     char linebuf[132];
  66.     char *line;
  67.     int command;
  68.     int status;
  69.     extern int find_command();
  70.     extern int expnd_args();
  71. #ifdef DEBUG
  72.     int i;
  73. #endif
  74.  
  75.     fprintf(STDERR,"hit <RETURN> to return to emulator,  <?> for help\n\n");
  76.     targc = 0;
  77.     while (TRUE)
  78.     {
  79.         if(targc > 1)
  80.             free_args();
  81.  
  82.         PROMPT;
  83.         linebuf[0] = 127;
  84. #ifndef REMOTE
  85.         Cconrs(linebuf);
  86. #else
  87.         Cconraux(linebuf);
  88. #endif
  89.         putc('\n', STDERR);
  90.         if(linebuf[1] == 0)
  91.         /* cancelled */
  92.         return;
  93.         
  94.         linebuf[(linebuf[1]+2)] = '\0';
  95.         line = &linebuf[2];
  96. #ifdef DEBUG
  97. printf("Line: |%s|\n", line);
  98. #endif
  99.  
  100.         targv[0] = line;
  101.         targc    = 1;
  102.     
  103.         /* pick up targv[0] */
  104.         while((*line != '\0') && (!isspace(*line)))
  105.             line++;
  106.  
  107.         if(*line != '\0')
  108.         {
  109.             *line++ = '\0';
  110.         }
  111.  
  112.         if((command = find_command(targv[0])) < 0)
  113.         {
  114.             fprintf(STDERR,"Invalid Command\n");
  115.             continue;
  116.         }
  117.  
  118.         if(expnd_args(line, comtab[command].expand))
  119.             /* too many args */
  120.             continue;
  121. #ifdef DEBUG
  122. printf("targc %d\n", targc);
  123. for(i = 0; i < targc; i++)
  124.     printf("%s ", targv[i]);
  125. printf("\n\n");
  126. #endif
  127.  
  128.         if((status = (*(comtab[command].routine))(targc, targv)) != 0)
  129.             fprintf(STDERR,"Exit Status %d\n", status);
  130.  
  131. #ifdef DEBUG
  132. printf("Exit Status %d\n", status);
  133. #endif
  134.  
  135.     } /* While */
  136. }
  137.  
  138. /*
  139.  * Straight sequential search thru comtab
  140.  */        
  141. int find_command(s)
  142. register char *s;
  143. {
  144.     register int i;
  145.  
  146.     for(i = 0; comtab[i].command != (char *)NULL; i++)
  147.     {
  148.         if(strcmp(s, comtab[i].command) == 0)
  149.             return i;
  150.     }
  151.  
  152.     return -1;
  153. }
  154.  
  155. /*
  156.  * Expand command line args, return TRUE if too many args, or Not matching Quotes
  157.  */
  158. int expnd_args(s, expand_wild)
  159. register char *s;
  160. int expand_wild;
  161. {
  162.     char next_arg[128];
  163.     register char *p;
  164.     register int contains_wild;
  165.     extern int add_argv();
  166.     extern int handl_wild();
  167.  
  168.     while(*s != '\0')
  169.     {
  170.         p = next_arg;
  171.         while(isspace(*s)) s++; /* skip leading space */
  172.         if(*s != '\0')
  173.         {
  174.             contains_wild = FALSE;
  175.             if(*s == '\047')
  176.             {
  177.                 /* Quoted arg */
  178.                 s++;
  179.                 while((*s != '\0') && (*s != '\047'))
  180.                     *p++ = *s++;
  181.                 *p = '\0';
  182.                 if(*s == '\0')
  183.                 {
  184.                     fprintf(STDERR,"No Matching Quote\n");
  185.                     return TRUE;
  186.                 }
  187.                 else
  188.                     s++;
  189.                 if(add_argv(next_arg))
  190.                     return TRUE;
  191.             }
  192.             else
  193.             {
  194.                 while(!isspace(*s) && (*s != '\0'))
  195.                 {
  196.                     contains_wild |= ISWILD(*s);
  197.                     *p++ = *s++;
  198.                 }
  199.                 *p = '\0';
  200.  
  201.                 if(contains_wild && expand_wild)
  202.                 {
  203.                     if(handl_wild(next_arg))
  204.                         return TRUE;
  205.                 }
  206.                 else
  207.                 {
  208.                     if(add_argv(next_arg))
  209.                         return TRUE;
  210.                 }
  211.             } /* if-else */
  212.         } /* If */
  213.     } /* while */
  214.  
  215.     return FALSE;
  216. }
  217.  
  218. /*
  219.  * add an arg to argv. Return TRUE if error
  220.  */
  221. int add_argv(s)
  222. char *s;
  223. {
  224.     extern char *strcpy();
  225. #ifdef __GNUC__
  226.     extern size_t strlen();
  227.     extern char *myalloc(unsigned int);
  228. #else
  229.     extern int strlen();
  230.     extern char *myalloc();
  231. #endif
  232.  
  233.     if(targc > (MAXARGS-1))
  234.     {
  235.         fprintf(STDERR,"Too many arguements (%d Max)\n", MAXARGS);
  236.         return TRUE;
  237.     }
  238.     targv[targc++] = strcpy(myalloc((unsigned int)(strlen(s)+1)), s);
  239.     
  240.     return FALSE;
  241.     
  242. }
  243.  
  244. /*
  245.  * expand wild card arguments. Return TRUE on error.
  246.  */
  247. int handl_wild(s)
  248. char *s;
  249. {
  250.     extern struct stat statbuf;
  251.     extern char *mkpathname();
  252.     
  253.     if(Fsfirst(s, 0x21) != 0)
  254.     {
  255.         /* No match */
  256.         fprintf(STDERR,"No Match for %s\n", s);
  257.         return TRUE;
  258.     }
  259.  
  260.     alltolower(statbuf.st_name);
  261.     if(add_argv(mkpathname(s, statbuf.st_name)))
  262.         return TRUE;
  263.  
  264.     while(Fsnext() == 0)
  265.     {
  266.         alltolower(statbuf.st_name);
  267.         if(add_argv(mkpathname(s, statbuf.st_name)))
  268.             return TRUE;
  269.     }
  270.  
  271.     return FALSE;
  272. }
  273.  
  274. /*
  275.  * Given a spec with a trailing wildcard and a base will name construct pathname
  276.  *
  277.  */
  278. char *mkpathname(spec, file)
  279. register char *spec, *file;
  280. {
  281.     extern char *rindex();
  282.     register char *p;
  283.  
  284.     if((p = rindex(spec, '\\')) == (char *)NULL)
  285.         /* no path name */
  286.         return file;
  287.  
  288.     while(*file != '\0')
  289.         *++p = *file++;
  290.     *++p = '\0';
  291.     
  292.     return spec;
  293. }
  294.  
  295. void free_args()
  296. {
  297.     register int i;
  298.     
  299.     for(i = 1; i < targc; i++)
  300.         free(targv[i]);
  301. }
  302.  
  303. /*
  304.  * remove files
  305.  *    Usage: rm [-i] files ... 
  306.  */    
  307. int rm(argc, argv)
  308. register int argc;
  309. register char **argv;
  310. {
  311.     register int interactive;
  312.     register int status;
  313.     extern int yesno();
  314.     extern int errno;
  315.  
  316.     interactive = FALSE;
  317.     status = 0;
  318.     while(--argc)
  319.     {
  320.         ++argv;
  321.         if( ((*argv)[0] == '-') && ((*argv)[1] == 'i') )
  322.             interactive = TRUE;
  323.         else
  324.         {
  325.             if(interactive)
  326.                 if(!yesno("rm: remove", *argv))
  327.                     continue;
  328.             if(unlink(*argv))
  329.             {
  330.                 status++;
  331.                 fprintf(STDERR, "%s: no such file\n", *argv);
  332.             }
  333.         }
  334.     }
  335.     return status;
  336. }
  337.  
  338. /*
  339.  * Prompt and return Yes/No truth value
  340.  *
  341.  */
  342. int yesno(p1, p2)
  343. register char *p1, *p2;
  344. {
  345.     char reply[16];
  346.  
  347.     fprintf(STDERR,"%s %s (y/n): ", p1, p2);
  348.     reply[0] = 16;
  349. #ifndef REMOTE
  350.     Cconrs(reply);
  351. #else
  352.     Cconraux(reply);
  353. #endif
  354.  
  355.     putc('\n', STDERR);
  356.     return ( (reply[2] == 'y') || (reply[2] == 'Y') );
  357.  
  358. }
  359.  
  360. /*
  361.  * copy files
  362.  *    Usage:
  363.  *        cp src dest
  364.  *        or
  365.  *        cp files.. directory
  366.  */
  367. int cp(argc, argv)
  368. int argc;
  369. char **argv;
  370. {
  371.     char dest[128];
  372.     register int status;
  373. #ifdef __GNUC__
  374.     extern size_t strlen();
  375. #else
  376.     extern int strlen();
  377. #endif
  378.     extern int cpy();
  379.     extern char *basename();
  380.     
  381.     status = 0;
  382.     if(argc > 3)
  383.     {
  384.         register int i;
  385.  
  386.         if(!existd(argv[argc-1]))
  387.         {
  388.             fprintf(STDERR,"%s does not exists or is not a directory\n",
  389.                 argv[argc-1]);
  390.             return 1;
  391.         }
  392.  
  393.         for(i = 1; i < argc - 1; i++)
  394.         {
  395.             strcpy(dest, argv[argc-1]);
  396.             if( (argv[argc-1])[((int)strlen(argv[argc-1])-1)] != '\\')
  397.                 strcat(dest, "\\");
  398.             strcat(dest, basename(argv[i]));
  399.  
  400.             fprintf(STDERR,"copying %s to %s\n", argv[i], dest);
  401.             status |= cpy(argv[i], dest);
  402.         }
  403.     }
  404.     else
  405.     {
  406.         if(argc > 2)
  407.         {
  408.             if(existd(argv[2]))
  409.             {
  410.                 /* dest is a directory */
  411.                 strcpy(dest, argv[2]);
  412.                 if( (argv[2])[((int)strlen(argv[2])-1)] != '\\')
  413.                     strcat(dest, "\\");
  414.  
  415.                 strcat(dest, basename(argv[1]));
  416.  
  417.                 fprintf(STDERR,"copying %s to %s\n", argv[1], dest);
  418.                 return (cpy(argv[1], dest));
  419.             }
  420.  
  421.             if(strcmp(argv[1], argv[2]) == 0)
  422.             {
  423.                 fprintf(STDERR,"Cannot copy a file onto itself\n");
  424.                 return 3;
  425.             }
  426.             status = cpy(argv[1], argv[2]);
  427.         }
  428.         else
  429.         {
  430.             fprintf(STDERR,"Usage: cp source dest or cp files .. directory\n");
  431.             return 2;
  432.         }
  433.     }
  434.  
  435.     return status;
  436. }
  437.  
  438.  
  439. /*
  440.  * Cpy src -> dest
  441.  *
  442.  */
  443. int cpy(src, dest)
  444. char *src, *dest;
  445. {
  446.     register int fps,fpd;
  447.     register long count;
  448.     register int status;
  449.  
  450.     status = 0;
  451.  
  452.     if((fps = Fopen(src, 0)) < (-3))
  453.     {
  454.         status = fps;
  455.         fprintf(STDERR,"%s: no such file\n", src);
  456.         return status;
  457.     }
  458.  
  459.     if((fpd = Fcreate(dest, 0)) < (-3))
  460.     {
  461.         if((fpd = Fopen(dest, 1)) < (-3))
  462.         {
  463.             Fclose(fps);
  464.             status = fpd;
  465.             fprintf(STDERR,"%s: cannot create\n",dest);
  466.             return status;
  467.         }
  468.     }
  469.     
  470.     while( (count = Fread(fps, (long)BBUFSIZ, bufr)) > 0L)
  471.     {
  472.         if(Fwrite(fpd, count, bufr) != count)
  473.         {
  474.             status = 1;
  475.             fprintf(STDERR,"Error Writing %s\n",dest);
  476.             break;
  477.         }
  478.     }
  479.     if(count < 0L)
  480.     {
  481.         status = 2;
  482.         fprintf(STDERR,"Error Reading %s\n", src);
  483.     }
  484.  
  485.     Fclose(fpd);
  486.     Fclose(fps);
  487.  
  488.     return status;
  489. }
  490.  
  491. #define haswild(X) \
  492. ( (rindex(X,'*') != (char *)NULL) || (rindex(X,'?') != (char *)NULL) )
  493.  
  494. /*
  495.  * list directories
  496.  */
  497. int ls(argc, argv)
  498. int argc;
  499. char **argv;
  500. {
  501.     char path[128];
  502.     register char *p;
  503.     extern char *rindex();
  504.     extern int existd();
  505.  
  506.     if(argc < 2)
  507.         lis("*.*");
  508.     else
  509.     {
  510.         while(--argc)
  511.         {
  512.             ++argv;
  513.             if((p = rindex(*argv,'\\')) == (char *)NULL)
  514.                 p = *argv;
  515.             else
  516.                 p++;
  517.             if(*p == '\0')
  518.             {
  519.                 strcpy(path, *argv);
  520.                 strcat(path,"*.*");
  521.             }
  522.             else
  523.             {
  524.                 if(haswild(p))
  525.                     strcpy(path, *argv);
  526.                 else
  527.                 {
  528.                     if(existd(p))
  529.                     {
  530.                         strcpy(path, *argv);
  531.                         strcat(path, "\\*.*");
  532.                     }
  533.                     else
  534.                         strcpy(path, *argv);
  535.                 }
  536.             }
  537.             lis(path);
  538.         } /* while */
  539.     }
  540.     
  541.     return 0;
  542. }
  543.  
  544. /*
  545.  * given a possibly wild carded string put out list of subtrees
  546.  *
  547.  */
  548. void lis(wild)
  549. char *wild;
  550. {
  551.     extern struct stat statbuf;
  552.     register int count;
  553.  
  554. #ifdef DEBUG
  555. printf("ls %s\n", wild);
  556. #endif
  557.  
  558.     if(Fsfirst(wild, 0x0020 | 0x0010) != 0)
  559.     {
  560.         fprintf(STDERR,"%s - no match.\n", wild);
  561.         return;
  562.     }
  563.  
  564.     count = 0;
  565.     alltolower(statbuf.st_name);
  566.     if(!((strcmp(statbuf.st_name,".") == 0) || 
  567.        (strcmp(statbuf.st_name, "..") == 0)))
  568.         putls(&statbuf, ++count);
  569.  
  570.     while(Fsnext() == 0)
  571.     {
  572.         alltolower(statbuf.st_name);
  573.         if(!((strcmp(statbuf.st_name,".") == 0) || 
  574.            (strcmp(statbuf.st_name, "..") == 0)))
  575.             putls(&statbuf, ++count);
  576.     }
  577.  
  578.     if((count % 4))
  579.         putc('\n', STDERR);
  580.  
  581. }
  582.  
  583. /*
  584.  * Put out a directory entry
  585.  */
  586. void putls(statbuf, count)
  587. register struct stat *statbuf;
  588. register int count;
  589. {
  590.     char dbuf[16];
  591.  
  592.     if((statbuf->st_mode) & 0x0010)
  593.     {
  594.         /* subtree */
  595.         strcpy(dbuf, statbuf->st_name);
  596.         strcat(dbuf, "/");
  597.         fprintf(STDERR,"%-13s      ", dbuf);
  598.     }
  599.     else
  600.         /* file */
  601.         fprintf(STDERR,"%-12s %5ld ", statbuf->st_name, statbuf->st_size);
  602.     
  603.     if(!(count %4))
  604.         putc('\n', STDERR);
  605. }
  606.  
  607. /*
  608.  * Change working directory
  609.  */
  610. int cd(argc, argv)
  611. int argc;
  612. char **argv;
  613. {
  614.     register char *d, *path;
  615.     register int drive;
  616.     extern char *index();
  617.  
  618.     if((argc < 2) || (argc > 2))
  619.     {
  620.         fprintf(STDERR,"Usage: cd directory\n");
  621.         return 1;
  622.     }
  623.  
  624.  
  625.     
  626.     if((d = index(argv[1],':')) == (char *)NULL)
  627.     {
  628.         /* Drive was not specified, must mean the current drive */
  629.         path = argv[1];
  630.     }
  631.     else
  632.     {
  633.         d--;
  634.         if(isupper(*d))
  635.         {
  636.             *d = tolower(*d);
  637.         }
  638.         drive = *d - 'a';
  639.         if(d[2] != '\\')    /* just gave D: */
  640.         {
  641.             /* we will shove in the '\' */
  642.             d[1] = '\\';
  643.             path = &d[1];
  644.         }
  645.         else
  646.             path = &d[2];
  647.  
  648.         /* Set the Drive */
  649.         if(Dsetdrv(drive) < 0)
  650.         {
  651.             fprintf(STDERR,"Could not set drive %c:\n", *d);
  652.             return 2;
  653.         }
  654.  
  655.     }
  656.  
  657.  
  658.     /* Set the Path */
  659.     if(Dsetpath(path) != 0)
  660.     {
  661.         fprintf(STDERR,"Could not set directory %s\n", path);
  662.         return 3;
  663.     }
  664.     
  665.     return 0;
  666.     
  667. }
  668.  
  669. /*
  670.  * pwd - figure out the current working directory
  671.  *
  672.  */
  673. int pwd()
  674. {
  675.     register int drive;
  676.     char _cwd[128];
  677.     
  678.     drive = Dgetdrv();
  679.     Dgetpath(&_cwd[3],0);
  680.     fprintf(STDERR,"%c:%s%s\n", (drive + 'a'),
  681.         ((_cwd[3] == '\\')? "" : "\\"), &_cwd[3]);
  682.  
  683.     return 0;
  684. }
  685.  
  686. /*
  687.  * Print free space
  688.  */
  689. int df(argc, argv)
  690. int argc;
  691. char **argv;
  692. {
  693.     struct {
  694.         long b_free;
  695.         long b_total;
  696.         long b_secsiz;
  697.         long b_clsiz;
  698.     } fbuf;
  699.  
  700.     register int drive;
  701.     register long ffree, total;
  702.     extern long drv_map;
  703.  
  704.     if(argc > 1)
  705.     {
  706.         ++argv;
  707.         drive = (*argv)[0];
  708.         if(isupper(drive))
  709.             drive = tolower(drive);
  710.  
  711.         drive = drive - 'a';
  712.         if((drv_map & (1L << drive)) == 0)
  713.         {
  714.             fprintf(STDERR,"Invalid Drive %c:\n", (drive + 'a'));
  715.             return 1;
  716.         }
  717.         drive +=1;
  718.     }
  719.     else
  720.         drive = Dgetdrv()+1;    /* default current drive */
  721.  
  722.     fprintf(STDERR,"Please Wait .....");
  723.     Dfree(&fbuf,drive);
  724.     ffree = fbuf.b_free * fbuf.b_clsiz * fbuf.b_secsiz;
  725.     total =    fbuf.b_total * fbuf.b_clsiz * fbuf.b_secsiz;
  726.     fprintf(STDERR,"\r%ld Bytes (", ffree);
  727.     prratio(STDERR, ffree, total);
  728.     fprintf(STDERR, ") Free on drive %c:\n", ((drive-1) + 'a'));
  729.  
  730.     return 0;
  731. }
  732.  
  733.  
  734. /*
  735.  * print a ratio
  736.  * avoid floats like the plague
  737.  */
  738. void prratio(stream, num, den)
  739. FILE *stream;
  740. long  num, den;
  741. {
  742.         register int q;                 /* Doesn't need to be long */
  743.  
  744.         if(num > 214748L) {             /* 2147483647/10000 */
  745.                 q = num / (den / 10000L);
  746.         } else {
  747.                 q = 10000L * num / den;         /* Long calculations, though */
  748.         }
  749.         if (q < 0) {
  750.                 putc('-', stream);
  751.                 q = -q;
  752.         }
  753.         fprintf(stream, "%d.%02d%%", q / 100, q % 100);
  754. }
  755.  
  756. /*
  757.  * Make directories
  758.  */
  759. int md(argc, argv)
  760. int argc;
  761. char **argv;
  762. {
  763.     register int status, s;
  764.  
  765.     status = 0;
  766.     while(--argc)
  767.     {
  768.         ++argv;
  769.         if(( s = Dcreate(*argv)))
  770.         {
  771.             status |= s;
  772.             fprintf(STDERR,"Could not create %s\n", *argv);
  773.         }
  774.     }
  775.  
  776.     return status;
  777. }
  778.  
  779. /*
  780.  * Remove directories
  781.  */
  782. int rd(argc, argv)
  783. int argc;
  784. char **argv;
  785. {
  786.     register int status, s;
  787.  
  788.     status = 0;
  789.     while(--argc)
  790.     {
  791.         ++argv;
  792.         if(( s = Ddelete(*argv)))
  793.         {
  794.             status |= s;
  795.             fprintf(STDERR,"Could not delete %s\n", *argv);
  796.         }
  797.     }
  798.  
  799.     return status;
  800. }
  801.  
  802.  
  803. /*
  804.  * Allocate memory with error check
  805.  *
  806.  */
  807. char *myalloc(size)
  808. unsigned int size;
  809. {
  810.     register char *m;
  811. #ifdef __GNUC__
  812.     extern void *malloc(size_t);
  813. #else
  814.     extern char *malloc();
  815. #endif
  816.  
  817. #ifdef __GNUC__
  818.     if((m = (char *)malloc((size_t)size)) == (char *)NULL)
  819. #else
  820.     if((m = (char *)malloc(size)) == (char *)NULL)
  821. #endif
  822.     {
  823.         fprintf(STDERR,"Out of Memory\nSorry, cannot continue\n");
  824.         exit(1);
  825.     }
  826.  
  827.     return m;
  828. }
  829.  
  830. /*
  831.  * Put out help
  832.  */
  833. int hhelp()
  834. {
  835.     register int i;
  836.  
  837. #ifdef REMOTE
  838.     fprintf(STDERR,"\n\t\t\t    Available Commands \n\n");
  839. #else
  840.     fprintf(STDERR,"\n\t\t\t   \033p Available Commands \033q\n\n");
  841. #endif
  842.     for(i = 0; comtab[i].command != (char *)NULL; i++)
  843.     {
  844.         fprintf(STDERR,"\t%s\t%s\n", comtab[i].command,
  845.             comtab[i].synopsis);
  846.     }
  847.     fprintf(STDERR,"\n\tor hit <RETURN> to exit to terminal emulator\n\n");
  848.     return 0;
  849.  
  850. }
  851.  
  852. /*
  853.  * Lower case string
  854.  */
  855. char *alltolower(s)
  856. register char *s;
  857. {
  858.     register char *p;
  859.  
  860.     for(p = s; *p != '\0'; p++)
  861.     {
  862.         if(isupper(*p))
  863.             *p = tolower(*p);
  864.     }
  865.     return s;
  866. }
  867.  
  868. /*
  869.  * return the base filename, given (potentially) a pathname
  870.  */
  871. char *basename(s)
  872. register char *s;
  873. {
  874.     register char *p;
  875.     extern char *rindex();
  876.  
  877.     if((p = rindex(s, '\\')) == (char *)NULL)
  878.     {
  879.         if((p = rindex(s, ':')) == (char *)NULL)
  880.             return s;
  881.         else
  882.             return ++p;
  883.     }
  884.     return ++p;
  885. }
  886.  
  887. #ifdef RECURSE
  888. int doszf(argc, argv)
  889. int argc;
  890. char **argv;
  891. {
  892.     extern int expandargs();
  893. #ifdef DDEBUG
  894. int i;
  895. printf("doszf: argc %d\n", argc);
  896. for(i = 0; i < argc; i++)
  897.     printf("%s ", argv[i]);
  898. printf("\n\n");
  899. #endif
  900.  
  901.     return(expandargs(dosz, argc, argv));
  902. }
  903.  
  904. #include "expandar.c"
  905.  
  906. #endif
  907.  
  908. #ifdef REMOTE
  909. /*
  910.  * Read a line from the Aux port
  911.  *
  912.  */
  913.  
  914. void Cconraux(l)
  915. char *l;
  916. {
  917.     register int c;
  918.     register int count;
  919.     register char *p;
  920.  
  921.     p = &l[2];
  922.     count = 0;
  923.  
  924.     while((c = get_a_c()) != '\n')
  925.     {
  926.         *p++ = c;
  927.         count++;
  928.     }
  929.     l[1] = count;
  930. }
  931.  
  932. static char _chr_buf[128];
  933. static int _n_chr = 0;
  934. static char *_next_chr = &_chr_buf[0];
  935. static char *_next_avail = &_chr_buf[0];
  936.  
  937. int get_a_c()
  938. {
  939.         register int c;
  940.  
  941.         if(_n_chr > 0)
  942.         {
  943.                 _n_chr--;
  944.                 return(*_next_avail++);
  945.         }
  946.         
  947.         _n_chr = 0;
  948.         _next_avail = &_chr_buf[0];
  949.         _next_chr = &_chr_buf[0];
  950.  
  951.         while( ((c = Bconin(1) & 0x7fff) != '\r') && (c != '\n'))
  952.         {
  953.                 if((c == '\003') || (c == '\025'))
  954.                 {
  955.             while(_n_chr-- > 0)
  956.                 wr_modem("\b \b");
  957.                         _n_chr = 0;
  958.                         _next_avail = &_chr_buf[0];
  959.                         _next_chr = &_chr_buf[0];
  960.  
  961.                 }
  962.  
  963.                 if((c == '\b') || (c == '\177'))
  964.                 {
  965.                         if(_n_chr > 0)
  966.                         {
  967.                                 _next_chr--;
  968.                                 _n_chr--;
  969.                                 wr_modem("\b \b");
  970.                         }
  971.                 }
  972.                 else
  973.                 {
  974.                         *_next_chr++ = c;
  975.                         _n_chr++;
  976.             Bconout(1, c);
  977.                 }
  978.         }
  979.  
  980.         *_next_chr = '\n';
  981.         return(*_next_avail++);
  982. }
  983. #endif /* REMOTE */
  984.  
  985. /* -eof- */
  986.